package com.kingre.et.service.impl;

import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.servlet.ServletUtilities;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.kingre.et.chart.PieChart;
import com.kingre.et.dao.ISchoolDAO;
import com.kingre.et.dao.ITdataDAO;
import com.kingre.et.dao.IUserDAO;
import com.kingre.et.model.School;
import com.kingre.et.model.Tdata;
import com.kingre.et.model.User;
import com.kingre.et.service.IDisSchoolReportService;

@Transactional
public class DisSchoolReportServiceImpl implements IDisSchoolReportService {
    private static final Logger logger = Logger.getLogger(DisSchoolReportServiceImpl.class);
    @Autowired
    private IUserDAO userDAO;
    @Autowired
    private ITdataDAO tdataDAO;
    @Autowired
    private ISchoolDAO schoolDAO;

    @Override
    public School getSchoolByUser(Integer userId) {
        return userDAO.get(userId).getSchool();
    }

    @Override
    public School getSchoolById(Integer id) {
        return schoolDAO.get(id);
    }

    @Override
    public Map<String, String> getSchoolUserResource(School school) {
        int sex[] = { 0, 0 };
        int degree[] = { 0, 0, 0 };
        int major[] = { 0, 0, 0, 0 };
        List<User> userList;
        if (school.getSchoolType() == 20)
            userList = userDAO.findBySchool(school);
        else
            userList = userDAO.findBySubSchool(school);
        logger.debug("userList =" + userList.size());
        for (int i = 0; i < userList.size(); i++) {
            if (userList.get(i).getSex() == 10)
                sex[0]++;
            else
                sex[1]++;
            if (userList.get(i).getDegree() == 10)
                degree[0]++;
            else if (userList.get(i).getDegree() == 20)
                degree[1]++;
            else
                degree[2]++;
            if (userList.get(i).getMajor() == 10)
                major[0]++;
            else if (userList.get(i).getMajor() == 20)
                major[1]++;
            else if (userList.get(i).getMajor() == 30)
                major[2]++;
            else
                major[3]++;
        }
        Map<String, String> map = new HashMap<String, String>();
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(1);
        map.put("sex10", String.valueOf(sex[0]));// 男
        map.put("sex20", String.valueOf(sex[1]));// 女
        map.put("sex11", nf.format(((double) sex[0]) / (sex[0] + sex[1])));
        map.put("sex21", nf.format(((double) sex[1]) / (sex[0] + sex[1])));

        map.put("degree10", String.valueOf(degree[0]));// 高职
        map.put("degree20", String.valueOf(degree[1]));// 本科
        map.put("degree30", String.valueOf(degree[2]));// 研究生
        map.put("degree11", nf.format(((double) degree[0]) / (degree[0] + degree[1] + degree[2])));
        map.put("degree21", nf.format(((double) degree[1]) / (degree[0] + degree[1] + degree[2])));
        map.put("degree31", nf.format(((double) degree[2]) / (degree[0] + degree[1] + degree[2])));

        map.put("major10", String.valueOf(major[0]));// 高职
        map.put("major20", String.valueOf(major[1]));// 本科
        map.put("major30", String.valueOf(major[2]));// 研究生
        map.put("major40", String.valueOf(major[3]));// 研究生
        map.put("major11", nf.format(((double) major[0]) / (major[0] + major[1] + major[2] + major[3])));
        map.put("major21", nf.format(((double) major[1]) / (major[0] + major[1] + major[2] + major[3])));
        map.put("major31", nf.format(((double) major[2]) / (major[0] + major[1] + major[2] + major[3])));
        map.put("major41", nf.format(((double) major[3]) / (major[0] + major[1] + major[2] + major[3])));

        return map;
    }

    @Override
    public Map<String, Double> getSchoolAVG(School school) {
        Map<String, Double> map = new HashMap<String, Double>();
        Object[] d = tdataDAO.findSchoolAVG(school);
        for (int i = 0; i < d.length; i++)
            map.put("a" + (i + 1), ((int) ((Double) d[i] * 100)) / 100d);
        return map;
    }

    @Override
    public Double getAllAVG(School school) {
        List<Tdata> list = tdataDAO.findAllAVG(school);
        double d = 0d;
        for (Tdata t : list) {
            d += t.getVAll();
        }
        return ((int) ((d / list.size()) * 100)) / 100d;
    }

    @Override
    public Map<String, List<Map<String, String>>> getLevelPercent(School school) {
        Map<String, List<Map<String, String>>> dataMap = new HashMap<String, List<Map<String, String>>>();
        List<Tdata> dataList = tdataDAO.findTdataBySchool(school);
        if (dataList == null)
            return null;
        int data[][] = { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } };
        for (Tdata t : dataList) {
            if (t.getV1() >= 70)
                data[0][0]++;
            else if (t.getV1() >= 60)
                data[0][1]++;
            else if (t.getV1() >= 40)
                data[0][2]++;
            else if (t.getV1() >= 30)
                data[0][3]++;
            else
                data[0][4]++;

            if (t.getV2() >= 70)
                data[1][0]++;
            else if (t.getV2() >= 60)
                data[1][1]++;
            else if (t.getV2() >= 40)
                data[1][2]++;
            else if (t.getV2() >= 30)
                data[1][3]++;
            else
                data[1][4]++;

            if (t.getV3() >= 70)
                data[2][0]++;
            else if (t.getV3() >= 60)
                data[2][1]++;
            else if (t.getV3() >= 40)
                data[2][2]++;
            else if (t.getV3() >= 30)
                data[2][3]++;
            else
                data[2][4]++;

            if (t.getV4() >= 70)
                data[3][0]++;
            else if (t.getV4() >= 60)
                data[3][1]++;
            else if (t.getV4() >= 40)
                data[3][2]++;
            else if (t.getV4() >= 30)
                data[3][3]++;
            else
                data[3][4]++;

            if (t.getV5() >= 70)
                data[4][0]++;
            else if (t.getV5() >= 60)
                data[4][1]++;
            else if (t.getV5() >= 40)
                data[4][2]++;
            else if (t.getV5() >= 30)
                data[4][3]++;
            else
                data[4][4]++;

            if (t.getV6() >= 70)
                data[5][0]++;
            else if (t.getV6() >= 60)
                data[5][1]++;
            else if (t.getV6() >= 40)
                data[5][2]++;
            else if (t.getV6() >= 30)
                data[5][3]++;
            else
                data[5][4]++;

            if (t.getV7() >= 70)
                data[6][0]++;
            else if (t.getV7() >= 60)
                data[6][1]++;
            else if (t.getV7() >= 40)
                data[6][2]++;
            else if (t.getV7() >= 30)
                data[6][3]++;
            else
                data[6][4]++;

            if (t.getV8() >= 70)
                data[7][0]++;
            else if (t.getV8() >= 60)
                data[7][1]++;
            else if (t.getV8() >= 40)
                data[7][2]++;
            else if (t.getV8() >= 30)
                data[7][3]++;
            else
                data[7][4]++;

            if (t.getV9() >= 70)
                data[8][0]++;
            else if (t.getV9() >= 60)
                data[8][1]++;
            else if (t.getV9() >= 40)
                data[8][2]++;
            else if (t.getV9() >= 30)
                data[8][3]++;
            else
                data[8][4]++;
        }
        Map<String, String> map;
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(1);
        for (int i = 0; i < 9; i++) {
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            for (int j = 0; j < 5; j++) {
                map = new HashMap<String, String>();
                map.put("number", String.valueOf(data[i][j]));
                map.put("percent",
                        nf.format(((double) data[i][j])
                                / (data[i][0] + data[i][1] + data[i][2] + data[i][3] + data[i][4])));
                list.add(map);
            }
            dataMap.put("vd" + (i + 1), list);
        }
        return dataMap;
    }

    @Override
    public Map<String, String> createChart(Map<String, List<Map<String, String>>> level, String[] levelName,
            String[] titleName) throws IOException {
        Map<String, String> fileMap = new HashMap<String, String>();
        List<Map<String, String>> list;

        StandardEntityCollection entityCollection = new StandardEntityCollection();
        ChartRenderingInfo info = new ChartRenderingInfo(entityCollection);
        for (int i = 1; i <= 9; i++) {
            list = level.get("vd" + i);
            String filename = ServletUtilities.saveChartAsPNG(
                    PieChart.generateChart(list, levelName, titleName[i - 1]), 450, 300, info, null);
            logger.debug("filename" + i + " =" + filename);
            fileMap.put("filename" + i, filename);
        }
        return fileMap;
    }

    @Override
    public List<Map<String, Double>> getWeakness(Map<String, Double> avgData, boolean isAsc) {
        List<Map<String, Double>> list = new ArrayList<Map<String, Double>>();
        List<Map<String, Double>> dataset = new ArrayList<Map<String, Double>>();
        Map<String, Double> map;
        for (int i = 1; i <= 9; i++) {
            map = new HashMap<String, Double>();
            map.put("vd", (double) (i - 1));
            map.put("value", avgData.get("a" + i));
            list.add(map);
        }
        list = order(list, isAsc);
        logger.debug("list =" + list.get(0));
        logger.debug("list =" + list.get(1));
        if (isAsc) {
            if (list.get(0).get("value") < 40) {
                dataset.add(list.get(0));
                if (list.get(1).get("value") < 40) {
                    dataset.add(list.get(1));
                }
            }
        } else {
            if (list.get(0).get("value") >= 60) {
                dataset.add(list.get(0));
                if (list.get(1).get("value") >= 60) {
                    dataset.add(list.get(1));
                }
            }
        }
        return dataset;
    }

    private List<Map<String, Double>> order(List<Map<String, Double>> dataset, boolean isAsc) {
        if (dataset.size() == 0)
            return dataset;
        Map<String, Double> map;
        for (int i = 0; i < dataset.size() - 1; i++) {
            for (int j = i + 1; j < dataset.size(); j++) {
                if (isAsc) {
                    if (dataset.get(i).get("value") > dataset.get(j).get("value")) {
                        map = new HashMap<String, Double>(dataset.get(i));
                        dataset.add(i, dataset.get(j));
                        dataset.remove(i + 1);
                        dataset.add(j, map);
                        dataset.remove(j + 1);
                    }
                } else if (dataset.get(i).get("value") < dataset.get(j).get("value")) {
                    map = new HashMap<String, Double>(dataset.get(i));
                    dataset.add(i, dataset.get(j));
                    dataset.remove(i + 1);
                    dataset.add(j, map);
                    dataset.remove(j + 1);
                }
            }
        }
        return dataset;
    }

}
